function convert(input) { alert('Error. Contact us if this keeps happening.'); document.getElementById('modal-contact').classList.add('show'); } window.ctMaxUploadFiles = 1; function _palMedianCut(pixels, depth, maxDepth) { if (depth >= maxDepth || pixels.length === 0) { if (pixels.length === 0) return []; var r = 0, g = 0, b = 0; for (var i = 0; i < pixels.length; i++) { r += pixels[i][0]; g += pixels[i][1]; b += pixels[i][2]; } return [[Math.round(r / pixels.length), Math.round(g / pixels.length), Math.round(b / pixels.length), pixels.length]]; } var minR = 255, maxR = 0, minG = 255, maxG = 0, minB = 255, maxB = 0; for (var j = 0; j < pixels.length; j++) { var p = pixels[j]; if (p[0] < minR) minR = p[0]; if (p[0] > maxR) maxR = p[0]; if (p[1] < minG) minG = p[1]; if (p[1] > maxG) maxG = p[1]; if (p[2] < minB) minB = p[2]; if (p[2] > maxB) maxB = p[2]; } var rangeR = maxR - minR, rangeG = maxG - minG, rangeB = maxB - minB; var channel = 0; if (rangeG >= rangeR && rangeG >= rangeB) channel = 1; else if (rangeB >= rangeR && rangeB >= rangeG) channel = 2; pixels.sort(function(a, b) { return a[channel] - b[channel]; }); var mid = pixels.length >> 1; return _palMedianCut(pixels.slice(0, mid), depth + 1, maxDepth) .concat(_palMedianCut(pixels.slice(mid), depth + 1, maxDepth)); } function _palToHex(r, g, b) { function h(n) { var s = n.toString(16).toUpperCase(); return s.length === 1 ? '0' + s : s; } return '#' + h(r) + h(g) + h(b); } function _palToHsl(r, g, b) { var rn = r / 255, gn = g / 255, bn = b / 255; var max = Math.max(rn, gn, bn), min = Math.min(rn, gn, bn); var h = 0, s = 0, l = (max + min) / 2; if (max !== min) { var d = max - min; s = l > 0.5 ? d / (2 - max - min) : d / (max + min); switch (max) { case rn: h = (gn - bn) / d + (gn < bn ? 6 : 0); break; case gn: h = (bn - rn) / d + 2; break; default: h = (rn - gn) / d + 4; break; } h = h / 6; } return { h: Math.round(h * 360), s: Math.round(s * 100), l: Math.round(l * 100) }; } var _palState = { pixels: null, fileName: 'image' }; function _palExtract(count) { if (!_palState.pixels) return []; var depth = Math.ceil(Math.log2(count)); var bins = _palMedianCut(_palState.pixels.slice(), 0, depth); bins.sort(function(a, b) { return b[3] - a[3]; }); return bins.slice(0, count); } function _palRender() { var count = parseInt(document.getElementById('pal-count').value, 10) || 6; document.getElementById('pal-count-label').textContent = count; var fmt = document.getElementById('pal-format').value; var bins = _palExtract(count); var grid = document.getElementById('pal-grid'); if (!grid) return; grid.innerHTML = ''; var lines = []; bins.forEach(function(c) { var hex = _palToHex(c[0], c[1], c[2]); var rgb = 'rgb(' + c[0] + ', ' + c[1] + ', ' + c[2] + ')'; var hsl = _palToHsl(c[0], c[1], c[2]); var hslStr = 'hsl(' + hsl.h + ', ' + hsl.s + '%, ' + hsl.l + '%)'; var primary = fmt === 'rgb' ? rgb : (fmt === 'hsl' ? hslStr : hex); var sw = document.createElement('div'); sw.className = 'pal-swatch'; sw.title = 'Click to copy ' + primary; sw.innerHTML = '
' + '
' + primary + '
' + (fmt === 'rgb' ? hex : (fmt === 'hsl' ? hex : rgb)) + '
'; sw.addEventListener('click', function() { _palCopy(primary); }); grid.appendChild(sw); lines.push(primary); }); var out = document.getElementById('box2'); if (out) out.value = lines.join('\n'); } function _palCopy(text) { var done = function() { var t = document.getElementById('pal-copied'); if (!t) return; t.textContent = 'Copied ' + text; t.classList.add('visible'); setTimeout(function() { t.classList.remove('visible'); }, 1200); }; if (navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(text).then(done, function(){ done(); }); } else { var ta = document.createElement('textarea'); ta.value = text; document.body.appendChild(ta); ta.select(); try { document.execCommand('copy'); } catch(e) {} document.body.removeChild(ta); done(); } } function processFile(blob, fileName) { _palState.fileName = fileName || 'image'; $('#file-drop-zone').addClass('collapsedDropZone'); (function(){ var $b=$('#file-drop-zone .upload-file-button'); var l=$b.data('change-label'); if(l) $b.text(l); })(); var img = new Image(); img.onload = function() { var maxSide = 200; var w = img.naturalWidth || img.width; var h = img.naturalHeight || img.height; var scale = Math.min(1, maxSide / Math.max(w, h)); var cw = Math.max(1, Math.round(w * scale)); var ch = Math.max(1, Math.round(h * scale)); var canvas = document.createElement('canvas'); canvas.width = cw; canvas.height = ch; var ctx = canvas.getContext('2d'); ctx.drawImage(img, 0, 0, cw, ch); var data; try { data = ctx.getImageData(0, 0, cw, ch).data; } catch (e) { alert('Could not read pixel data: ' + (e && e.message || e)); return; } var pixels = []; for (var i = 0; i < data.length; i += 4) { if (data[i + 3] < 128) continue; pixels.push([data[i], data[i + 1], data[i + 2]]); } if (pixels.length === 0) { alert('This image is fully transparent. Cannot extract a palette.'); return; } _palState.pixels = pixels; var ws = document.getElementById('pal-workspace'); if (ws) ws.style.display = 'block'; _palRender(); }; img.onerror = function() { alert('Could not decode this image file.'); }; var url = URL.createObjectURL(blob); img.src = url; } function _palInit() { var c = document.getElementById('pal-count'); if (c) c.addEventListener('input', _palRender); var f = document.getElementById('pal-format'); if (f) f.addEventListener('change', _palRender); } function convert(input) { return document.getElementById('box2') ? document.getElementById('box2').value : ''; } document.addEventListener('DOMContentLoaded', _palInit); if (document.readyState !== 'loading') _palInit(); var _loadedScripts = {}; function loadScriptPromise(url) { if (_loadedScripts[url]) return _loadedScripts[url]; _loadedScripts[url] = new Promise(function (resolve, reject) { var s = document.createElement('script'); s.src = url; s.onload = resolve; s.onerror = reject; document.head.appendChild(s); }); return _loadedScripts[url]; } function replaceAll(find, replace, str) { return str.replace(new RegExp(find, 'g'), replace); } function beautify(str) { var result = ''; var length = str.length; var i = 0; var braceCountLeft = 0; var braceCountRight = 0; var withinQuotes = false; while (i < length) { var c = str[i]; if (c == '"' && (i == 0 || c[i - 1] != '\\')) { // non-escaped quotes withinQuotes = !withinQuotes; } if (!withinQuotes && (c == '}' || c == '{' || c == ',')) { console.log('Start####' + result); // look back and remove carriage returns and whitespace that are already there var resultIndex = result.length - 1; while (resultIndex >= 0 && (result[resultIndex] == ' ' || result[resultIndex] == '\r' || result[resultIndex] == '\n' || result[resultIndex] == '\t')) { resultIndex = resultIndex - 1; result = result.substr(0, resultIndex + 1); console.log('char ' + result[resultIndex] + '-----' + result + 'zzz ' + result.length + ' ' + resultIndex); } if (c == '{') { braceCountLeft++; result += c + '\r' + GetTabs(braceCountLeft - braceCountRight); } else if (c == '}') { braceCountRight++; // precede with carriage return result += '\r' + GetTabs(braceCountLeft - braceCountRight) + c; } else if (c == ',') { result += c + '\r' + GetTabs(braceCountLeft - braceCountRight); } var nextChar = ''; // advance through whitespace and remove carriage returns that are already there while (i < length && (str[i + 1] == ' ' || str[i + 1] == '\r' || str[i + 1] == '\n' || str[i + 1] == '\t')) { i++; } } else { result += str[i]; } i++; } return result; } function GetTabs(count) { var result = ''; for (var i = 0; i < count; i++) { result += ' '; } return result; }